package com.slicktechnologies.server;

import static com.googlecode.objectify.ObjectifyService.ofy;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.google.appengine.api.datastore.ReadPolicy.Consistency;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.ObjectifyService;
import com.googlecode.objectify.cmd.Query;
import com.simplesoftwares.client.library.appstructure.SuperModel;
import com.simplesoftwares.client.library.appstructure.search.Filter;
import com.simplesoftwares.client.library.appstructure.search.MyQuerry;
import com.simplesoftwares.client.library.libservice.CategoryTypeService;
import com.slicktechnologies.shared.common.helperlayer.ConfigCategory;
import com.slicktechnologies.shared.common.helperlayer.Type;

@SuppressWarnings("serial")
public class CategoryTypeImpl extends RemoteServiceServlet implements CategoryTypeService 
{
	static
	{
		try
		{

		}
		catch(Exception e)
		{
			e.printStackTrace();

		}
	}

	@Override
	public HashMap<ConfigCategory, ArrayList<Type>> LoadOneToManyHashMap(MyQuerry oneQuerry, MyQuerry manyQuerry)
	{

		CategoryTypeImpl impl=new CategoryTypeImpl();
		//Holds the one type keys;
		ArrayList<Key<?>> keyarraylists=new ArrayList<Key<?>>();
		//Get all keys of one
		ArrayList<SuperModel> onelist =impl.getSearchResult(oneQuerry);

		//System.out.println("Size of OneList **********************************  "+onelist.size());

		for(SuperModel temp:onelist)
		{
			Key<?>key=Key.create(temp);
			keyarraylists.add(key);
		}

		//This hash map we have to fill

		HashMap<ConfigCategory, ArrayList<Type>>hashmap=new HashMap<ConfigCategory,ArrayList<Type>>();

		//create Hash Map

		ArrayList<Type>manylist=new ArrayList<Type>();
		int i=0;
		for(SuperModel model:onelist)
		{

			manyQuerry=createMyQerry(manyQuerry,keyarraylists.get(i));


			ArrayList<SuperModel>templist=impl.getSearchResult(manyQuerry);

			//System.out.println("Size of Many List***************"+templist.size());

			manylist=new ArrayList<Type>();
			for(SuperModel m:templist)
				manylist.add((Type) m);
			//System.out.println("ManyList:::"+manylist);
			hashmap.put((ConfigCategory) model,manylist);

			i++;
		}
		return hashmap;
	}
	
	/**
	 * Creates the my qerry.
	 *
	 * @param querry many querry which contains only connecting string
	 * @param key key of one
	 * @return the my querry returns many querry with value i.e is key
	 */
	private MyQuerry createMyQerry(MyQuerry querry,Key<?>key)
	{
		Vector<Filter>myfiltervalue=querry.getFilters();

		Filter filtervalue=myfiltervalue.get(0);

		String connector=filtervalue.getQuerryString();

		Vector<Filter> temp=new Vector<Filter>();
		Filter value=new Filter();
		value.setQuerryString(connector);
		value.setObjectifykey(key);
		temp.add(value);
		querry.setFilters(temp);
		return querry;
	}

	/* (non-Javadoc)
	 * @see com.simplesoftwares.client.library.libservice.GenricService#getSearchResult(com.simplesoftwares.client.library.appstructure.search.MyQuerry)
	 */
	@Override
	public ArrayList<SuperModel> getSearchResult(MyQuerry quer)
	{
		//Clear the session
		ofy().clear();
		Query<? extends SuperModel> query = null;
		//Get the querry
		query=ofy().load().type(quer.getQuerryObject().getClass());
		
		Logger logger = Logger.getLogger("NameOfYourLogger");

		//Get the 
		if(quer.getFilters()!=null)
		{
			for(int i=0;i<quer.getFilters().size();i++)
			{
				String conditionField=quer.getFilters().get(i).getQuerryString();

				Object value=quer.getFilters().get(i).geFilterValue();


				if(value instanceof Date)
				{
					/*logger.log(Level.SEVERE,"Condition Value before parsed "+value.toString());
			    	  Date condDate= parseDate((Date) value);
			    	 // Very dangerous patch learn internationalization and recode
			    	 Calendar c = Calendar.getInstance(); 
			    	 c.setTime(condDate); 
			    	 c.add(Calendar.DATE, 1);
			    	 condDate = c.getTime();
			    	 condDate= parseDate((Date) condDate);
			    	 logger.log(Level.SEVERE,"Condition Value When parsed "+condDate);
			    	 logger.log(Level.SEVERE,"Condition Field When parsed "+conditionField);
			    	 query=query.filter(conditionField,condDate);*/

				}
				else
				{

					query=query.filter(conditionField,value);
					logger.log(Level.SEVERE,"Condition Field "+conditionField);
					logger.log(Level.SEVERE,"Condition Value "+value);
					logger.log(Level.SEVERE,"Size of Querry "+query.count());

				}


				//logger.log(Level.SEVERE,"Condition Field "+conditionField);
				// logger.log(Level.SEVERE,"Condition Value "+value);
				//  logger.log(Level.SEVERE,"Size of Querry "+query.count());

			}

		}    
		ObjectifyService.reset();
		ofy().consistency(Consistency.STRONG);
		logger.log(Level.SEVERE,"Size of Querry "+query.count());
		logger.log(Level.SEVERE,"Type Of"+quer.getQuerryObject().getClass());
		ArrayList<SuperModel> list=new ArrayList<SuperModel>();
		ofy().clear();
		for(SuperModel i:query)
		{
			list.add(i);
		}   


		return list;
	}

}